import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
import { computed, defineComponent, PropType, VNode } from 'vue';
import {
  IDEDataView,
  ILayoutPanel,
  IUIActionGroupDetail,
} from '@ibiz/model-core';
import { IMDControlGroupState } from '@ibiz-template/runtime';
import { DataViewControlController } from './data-view.controller';
import './data-view.scss';

export const DataViewControl = defineComponent({
  name: 'IBizDataViewControl',
  props: {
    modelData: { type: Object as PropType<IDEDataView>, required: true },
    context: { type: Object as PropType<IContext>, required: true },
    params: { type: Object as PropType<IParams>, default: () => ({}) },

    /**
     * 部件行数据默认激活模式
     * - 0 不激活
     * - 1 单击激活
     * - 2 双击激活(默认值)
     *
     * @type {(number | 0 | 1 | 2)}
     */
    mdctrlActiveMode: { type: Number, default: 2 },
    singleSelect: { type: Boolean, default: true },
  },
  setup(props) {
    const c = useControlController(
      (...args) => new DataViewControlController(...args),
    );
    const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`);

    // 是否可以加载更多
    const isLodeMore = computed(() => {
      return c.state.items.length >= c.state.total || c.state.isLoading;
    });

    // 绘制项布局面板
    const renderPanelItem = (item: IData, modelData: ILayoutPanel): VNode => {
      const { context, params } = c;
      return (
        <iBizControlShell
          data={item}
          modelData={modelData}
          context={context}
          params={params}
          onClick={(): Promise<void> => c.onRowClick(item)}
          onDblclick={(): Promise<void> => c.onDbRowClick(item)}
        ></iBizControlShell>
      );
    };
    // 绘制项行为
    const renderItemAction = (item: IData): VNode => {
      return (
        <iBizActionToolbar
          class={ns.bem('item-content', 'bottom', 'actions')}
          action-details={
            c.getOptItemModel()!.deuiactionGroup?.uiactionGroupDetails
          }
          actions-state={c.getOptItemAction(item)}
          onActionClick={(
            detail: IUIActionGroupDetail,
            event: MouseEvent,
          ): Promise<void> => c.onActionClick(detail, item, event)}
        ></iBizActionToolbar>
      );
    };

    // 绘制默认项
    const renderDefaultItem = (item: IData): VNode => {
      return (
        <div class={ns.b('item-content')}>
          <div class={ns.be('item-content', 'top')}>
            <div class={ns.bem('item-content', 'top', 'title')}>
              {item.srfmajortext}
            </div>
            <div class={ns.bem('item-content', 'top', 'description')}>
              {item.content}
            </div>
          </div>
          {c.getOptItemModel() ? (
            <div class={ns.be('item-content', 'bottom')}>
              {renderItemAction(item)}
            </div>
          ) : null}
        </div>
      );
    };

    // 绘制卡片
    const renderCard = (item: IData): VNode => {
      // 是否选中数据
      const findIndex = c.state.selectedData.findIndex(data => {
        return data.srfkey === item.srfkey;
      });
      const cardClass = [ns.b('item'), ns.is('active', findIndex !== -1)];
      const cardStyle = {};
      if (c.model.cardWidth) {
        Object.assign(cardStyle, {
          width: `${c.model.cardWidth}px`,
        });
      }
      if (c.model.cardHeight) {
        Object.assign(cardStyle, {
          height: `${c.model.cardHeight}px`,
        });
      }
      const panel = props.modelData.itemLayoutPanel;

      return (
        <el-card
          shadow='hover'
          class={cardClass}
          body-style={cardStyle}
          onClick={(): Promise<void> => c.onRowClick(item)}
          onDblclick={(): Promise<void> => c.onDbRowClick(item)}
        >
          {panel ? renderPanelItem(item, panel) : renderDefaultItem(item)}
        </el-card>
      );
    };

    // 绘制分组
    const renderGroup = (group: IMDControlGroupState): VNode => {
      return (
        <el-collapse-item
          title={group.caption}
          class={ns.be('group-content', 'item')}
        >
          {group.children.length > 0 ? (
            group.children.map(child => {
              return renderCard(child);
            })
          ) : (
            <div class={ns.bem('group-content', 'item', 'empty')}>无数据</div>
          )}
        </el-collapse-item>
      );
    };

    // 绘制卡片内容
    const renderDataViewContent = (): VNode | VNode[] => {
      if (c.model.enableGroup) {
        return (
          <el-collapse class={ns.b('group-content')}>
            {c.state.groups.map(group => {
              return (
                <div class={[ns.b('scroll-item')]}>{renderGroup(group)}</div>
              );
            })}
          </el-collapse>
        );
      }
      return c.state.items.map(item => {
        return <div class={[ns.b('scroll-item')]}>{renderCard(item)}</div>;
      });
    };

    // 绘制滑动加载更多数据
    const renderLoadMore = (): VNode => {
      return (
        <div
          class={ns.b('scroll')}
          v-infinite-scroll={(): Promise<void> => c.loadMore()}
          infinite-scroll-distance={10}
          infinite-scroll-disabled={isLodeMore.value}
        >
          {renderDataViewContent()}
        </div>
      );
    };

    const renderNoData = (): VNode | undefined => {
      // 未加载不显示无数据
      const { isLoaded } = c.state;
      if (!isLoaded) {
        return;
      }
      return <iBizNoData></iBizNoData>;
    };

    return {
      c,
      ns,
      renderLoadMore,
      renderNoData,
    };
  },
  render() {
    const { items, isCreated } = this.c.state;
    return (
      <iBizControlBase controller={this.c}>
        {isCreated &&
          (items.length > 0 ? this.renderLoadMore() : this.renderNoData())}
      </iBizControlBase>
    );
  },
});
